package dbrpc

import (
	"bytes"
	"database/sql"
	"dub/define/grpcmodel"
	"dub/utils"
	"fmt"
	"golang.org/x/net/context"
)

//广告
type DbRpcAdvert struct {
	log *utils.Logger
}

func (d *DbRpcAdvert) Update(ctx context.Context, args *grpcmodel.ModelDbRpcAdvertReqModel) (reply *grpcmodel.ModelDbRpcAdvertResModel, err error) {
	reply = &grpcmodel.ModelDbRpcAdvertResModel{}
	for {
		if args.GetModelDbRpcAdvert().GetAdvertId() < 1 {
			reply.Err = 3
			break
		}
		sql_buf := bytes.Buffer{}
		sql_buf.WriteString("update dubadvert set advertId=?")
		params := make([]interface{}, 0)
		params = append(params, args.GetModelDbRpcAdvert().GetAdvertId())

		if args.GetIsAllUpdate() || (!args.GetIsAllUpdate() && args.GetModelDbRpcAdvert().GetAdCSPrice() > 0) {
			sql_buf.WriteString(", adCSPrice=?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdCSPrice())
		}
		if args.GetIsAllUpdate() || (!args.GetIsAllUpdate() && args.GetModelDbRpcAdvert().GetAdCount() > 0) {
			sql_buf.WriteString(", adCount=adCount+?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdCount())
		}
		if args.GetIsAllUpdate() || (!args.GetIsAllUpdate() && args.GetModelDbRpcAdvert().GetAdStatus() > 0) {
			sql_buf.WriteString(", adStatus=?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdStatus())
		}
		if args.GetIsAllUpdate() || (!args.GetIsAllUpdate() && args.GetModelDbRpcAdvert().GetAdTitle() != "") {
			sql_buf.WriteString(", adTitle=?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdTitle())
		}
		if args.GetIsAllUpdate() || (!args.GetIsAllUpdate() && args.GetModelDbRpcAdvert().GetAdType() > 0) {
			sql_buf.WriteString(", adType=?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdType())
		}
		if args.GetIsAllUpdate() || (!args.GetIsAllUpdate() && args.GetModelDbRpcAdvert().GetAdUrl() != "") {
			sql_buf.WriteString(", adUrl=?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdUrl())
		}
		if args.GetIsAllUpdate() || (!args.GetIsAllUpdate() && args.GetModelDbRpcAdvert().GetAdTCount() > 0) {
			sql_buf.WriteString(", adTCount=?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdTCount())
		}
		sql_buf.WriteString(" where advertId=?")
		params = append(params, args.GetModelDbRpcAdvert().GetAdvertId())

		dbAccounts := NewDbProxy().Get(DB_Accounts)
		sql_str := sql_buf.String()
		d.log.Infof("def_func_db_advert.go Update method exec %s params is %+v\n", sql_str, params)
		res, err := dbAccounts.Exec(sql_buf.String(), params...)

		if err != nil {
			d.log.Infof("def_func_db_advert.go Update method dbAccounts.Exec err. %v\n", err)
			reply.Err = 2
			break
		}

		up_count, err := res.RowsAffected()
		if err != nil {
			d.log.Infof("def_func_db_advert.go Update method res.RowsAffected err. %v\n", err)
			reply.Err = 2
			break
		}
		if up_count < 1 {
			reply.Err = 1
		}
		reply.AdvertId = args.GetModelDbRpcAdvert().GetAdvertId()
		break
	}
	return
}

func (d *DbRpcAdvert) Add(ctx context.Context, args *grpcmodel.ModelDbRpcAdvertReqModel) (reply *grpcmodel.ModelDbRpcAdvertResModel, err error) {
	reply = &grpcmodel.ModelDbRpcAdvertResModel{}
	for {
		sql_pre_buf := bytes.Buffer{}
		sql_pre_buf.WriteString("insert into dubadvert (adCount,adType,adCSPrice,adStatus,adTCount")
		sql_after_buf := bytes.Buffer{}
		sql_after_buf.WriteString(") values (?,?,?,?,?")
		params := make([]interface{}, 0)
		params = append(params, args.GetModelDbRpcAdvert().GetAdCount())
		params = append(params, args.GetModelDbRpcAdvert().GetAdType())
		params = append(params, args.GetModelDbRpcAdvert().GetAdCSPrice())
		params = append(params, args.GetModelDbRpcAdvert().GetAdStatus())
		params = append(params, args.GetModelDbRpcAdvert().GetAdTCount())

		if args.GetModelDbRpcAdvert().GetAdTitle() != "" {
			sql_pre_buf.WriteString(", adTitle")
			sql_after_buf.WriteString(",?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdTitle())
		}
		if args.GetModelDbRpcAdvert().GetAdUrl() != "" {
			sql_pre_buf.WriteString(", adUrl")
			sql_after_buf.WriteString(",?")
			params = append(params, args.GetModelDbRpcAdvert().GetAdUrl())
		}
		sql_after_buf.WriteString(")")
		sql_pre_buf.WriteString(sql_after_buf.String())

		sql_str := sql_pre_buf.String()
		d.log.Infof("def_func_db_advert.go Add method exec %s params is %+v\n", sql_str, params)
		dbAccounts := NewDbProxy().Get(DB_Accounts)
		res, err := dbAccounts.Exec(sql_str, params...)

		if err != nil {
			reply.Err = 2
			d.log.Errorf("def_func_db_advert.go Add method dbAccounts.Exec err. %v\n", err)
			break
		}

		up_id, err := res.LastInsertId()
		if err != nil {
			reply.Err = 2
			break
		}

		reply.AdvertId = uint32(up_id)
		reply.Err = 0
		break
	}
	return
}

func (d *DbRpcAdvert) FindAdvert(ctx context.Context, args *grpcmodel.ModelDbRpcAdvertReqFind) (reply *grpcmodel.ModelDbRpcAdvertResFindAdvert, err error) {
	reply = &grpcmodel.ModelDbRpcAdvertResFindAdvert{}
	for {
		sql_after_str := bytes.Buffer{}
		sql_after_str.WriteString("from dubadvert where adStatus>0")
		params := make([]interface{}, 0)

		if args.GetAdvertId() > 0 {
			sql_after_str.WriteString(" and advertId=?")
			params = append(params, args.GetAdvertId())
		}

		sql_after_str.WriteString(" limit 1")
		sql_str := fmt.Sprintf("select advertId,adTitle,adUrl,adType,adCSPrice,adCount,adStatus,adTCount %s", sql_after_str.String())
		dbAccounts := NewDbProxy().Get(DB_Accounts)
		d.log.Infof("def_func_db_advert.go FindAdvert method exec %s params is %+v\n", sql_str, params)
		row := dbAccounts.QueryRow(sql_str, params...)
		var (
			advertId, adType, adCount, adStatus, adTCount sql.NullInt64
			adCSPrice                                     sql.NullFloat64
			adTitle, adUrl                                sql.NullString
		)
		err = row.Scan(&advertId, &adTitle, &adUrl, &adType, &adCSPrice, &adCount, &adStatus, &adTCount)

		switch {
		case err == sql.ErrNoRows:
			err = nil
			reply.Err = 1
		case err != nil:
			reply.Err = 2
			d.log.Errorf("def_func_db_advert.go FindAdvert method dbAccounts.QueryRow err. %v\n", err)
		default:
			model := &grpcmodel.ModelDbRpcAdvert{}
			if advertId.Valid {
				model.AdvertId = uint32(advertId.Int64)
			}
			if adType.Valid {
				model.AdType = uint32(adType.Int64)
			}
			if adCount.Valid {
				model.AdCount = uint32(adCount.Int64)
			}
			if adStatus.Valid {
				model.AdStatus = uint32(adStatus.Int64)
			}
			if adCSPrice.Valid {
				model.AdCSPrice = adCSPrice.Float64
			}
			if adTitle.Valid {
				model.AdTitle = adTitle.String
			}
			if adUrl.Valid {
				model.AdUrl = adUrl.String
			}
			if adTCount.Valid {
				model.AdTCount = uint32(adTCount.Int64)
			}
			reply.ModelDbRpcAdvert = model
		}
		break
	}
	return
}

func (d *DbRpcAdvert) Find(ctx context.Context, args *grpcmodel.ModelDbRpcAdvertReqFind) (reply *grpcmodel.ModelDbRpcAdvertResFind, err error) {
	reply = &grpcmodel.ModelDbRpcAdvertResFind{}
	for {
		after_from_buf := bytes.Buffer{}
		params := make([]interface{}, 0)
		after_from_buf.WriteString("from dubadvert where adStatus>0")

		if args.GetAdvertId() > 0 {
			after_from_buf.WriteString(" and advertId=?")
			params = append(params, args.GetAdvertId())
		}

		if args.GetPageSize() > 1 {
			sql_str := fmt.Sprintf("select count(advertId) %s", after_from_buf.String())
			d.log.Infof("def_func_db_advert.go Find method exec %s params is %+v\n", sql_str, params)
			dbAccounts := NewDbProxy().Get(DB_Accounts)
			row := dbAccounts.QueryRow(sql_str, params...)
			var total sql.NullInt64
			err = row.Scan(&total)
			if err != nil {
				d.log.Errorf("def_func_db_advert.go Find method dbAccounts.QueryRow err. %v\n", err)
				reply.Err = 2
				break
			}
			if total.Valid {
				if total.Int64 < 1 {
					break
				}
				reply.Total = uint32(total.Int64)
			}

			after_from_buf.WriteString(" limit ?,?")
			params = append(params, args.GetStartRow(), args.GetPageSize())
		}

		sql_str := fmt.Sprintf("select advertId,adTitle,adUrl,adType,adCSPrice,adCount,adStatus,adTCount %s", after_from_buf.String())
		d.log.Infof("def_func_db_advert.go Find method exec %s params is %+v\n", sql_str, params)
		dbAccounts := NewDbProxy().Get(DB_Accounts)
		rows, err := dbAccounts.Query(sql_str, params...)
		switch {
		case err == sql.ErrNoRows:
			err = nil
			reply.Err = 1
		case err != nil:
			reply.Err = 2
			d.log.Errorf("def_func_db_advert.go Find method dbAccounts.Query err. %v\n", err)
		default:
			reply.Rows = make([]*grpcmodel.ModelDbRpcAdvert, 0)
			for rows.Next() {
				var (
					advertId, adType, adCount, adStatus, adTCount sql.NullInt64
					adCSPrice                                     sql.NullFloat64
					adTitle, adUrl                                sql.NullString
				)
				err := rows.Scan(&advertId, &adTitle, &adUrl, &adType, &adCSPrice, &adCount, &adStatus, &adTCount)
				if err != nil {
					reply.Err = 2
					d.log.Errorf("def_func_db_advert.go Find method rows.Scan err. %v\n", err)
				}
				model := &grpcmodel.ModelDbRpcAdvert{}
				if advertId.Valid {
					model.AdvertId = uint32(advertId.Int64)
				}
				if adType.Valid {
					model.AdType = uint32(adType.Int64)
				}
				if adCount.Valid {
					model.AdCount = uint32(adCount.Int64)
				}
				if adStatus.Valid {
					model.AdStatus = uint32(adStatus.Int64)
				}
				if adCSPrice.Valid {
					model.AdCSPrice = adCSPrice.Float64
				}
				if adTitle.Valid {
					model.AdTitle = adTitle.String
				}
				if adUrl.Valid {
					model.AdUrl = adUrl.String
				}
				if adTCount.Valid {
					model.AdTCount = uint32(adTCount.Int64)
				}
				reply.Rows = append(reply.Rows, model)
			}
		}
		break
	}
	return
}

var _dbRpcAdvert *DbRpcAdvert

func NewDbRpcAdvert() *DbRpcAdvert {
	if _dbRpcAdvert == nil {
		_dbRpcAdvert = &DbRpcAdvert{
			log: utils.NewLogger(),
		}
	}
	return _dbRpcAdvert
}
